﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TencentMapSdk.Entity;

namespace TencentMapSdk
{
    /// <summary>
    /// 地点云Api
    /// </summary>
    public class CloudApi : BaseApi
    {
        static JsonSerializerSettings settings = new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Ignore
        };
        /// <summary>
        /// 查询表结构
        /// </summary>
        /// <param name="table_id"></param>
        /// <param name="key"></param>
        /// <param name="secretKey"></param>
        /// <param name="output"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        public static MapResponse<TableCollection> QueryStructure(string table_id, string key, string secretKey, string output = "json", string callback = null)
        {
            string query = GetRequestBuilder.Create(secretKey, "/place_cloud/table/list")
                .WithKeyValue("key", key)
                .WithKeyValue("table_id", table_id)
                .WithKeyValue("output", output)
                .WithKeyValue("callback", callback)
                .BuildQueryString();
            string url = host + query;
            var response = Get<MapResponse<TableCollection>>(url, out string body);
            response.Body = body;
            return response;
        }

        /// <summary>
        /// 插入数据
        /// </summary>
        /// <param name="data"></param>
        /// <param name="key"></param>
        /// <param name="secretKey"></param>
        /// <returns></returns>
        /// <remarks>CloudData对象中不需要设置的参数，统一设置为null，不要设置为其他空字符串，值类型也必须设置为可空。否则会导致签名失败</remarks>
        public static MapResponse<CloudCreateDataResult> CreateData(CloudCreateData data, string key, string secretKey)
        {
            string datas = JsonConvert.SerializeObject(data, Formatting.None, settings);
            string query = PostRequestBuilder.Create(secretKey, "/place_cloud/data/create")
                .WithKeyValue("data", JsonConvert.SerializeObject(data.Data, Formatting.None, settings))
                .WithKeyValue("key", data.Key)
                .WithKeyValue("table_id", data.TableId)
                .BuildQueryString();
            string url = host + query;
            var response = Post<MapResponse<CloudCreateDataResult>>(url, datas, out string body);
            response.Body = body;
            return response;
        }

        /// <summary>
        /// 修改数据
        /// </summary>
        /// <param name="data"></param>
        /// <param name="key"></param>
        /// <param name="secretKey"></param>
        /// <returns></returns>
        public static MapResponse<CloudUpdateDataResult> UpdateData(CloudUpdateData data, string key, string secretKey)
        {
            string datas = JsonConvert.SerializeObject(data, Formatting.None, settings);
            string query = PostRequestBuilder.Create(secretKey, "/place_cloud/data/update")
                .WithKeyValue("data", JsonConvert.SerializeObject(data.Data, Formatting.None, settings))
                .WithKeyValue("key", data.Key)
                .WithKeyValue("table_id", data.TableId)
                .WithKeyValue("filter", data.Filter)
                .BuildQueryString();
            string url = host + query;
            var response = Post<MapResponse<CloudUpdateDataResult>>(url, datas, out string body);
            response.Body = body;
            return response;
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="data"></param>
        /// <param name="key"></param>
        /// <param name="secretKey"></param>
        /// <returns></returns>
        public static MapResponse<CloudDeleteDataResult> DeleteData(CloudDeleteData data, string key, string secretKey)
        {
            string datas = JsonConvert.SerializeObject(data, Formatting.None, settings);
            string query = PostRequestBuilder.Create(secretKey, "/place_cloud/data/delete")
                .WithKeyValue("key", data.Key)
                .WithKeyValue("table_id", data.TableId)
                .WithKeyValue("filter", data.Filter)
                .BuildQueryString();
            string url = host + query;
            var response = Post<MapResponse<CloudDeleteDataResult>>(url, datas, out string body);
            response.Body = body;
            return response;
        }

        /// <summary>
        /// 获取所有数据li
        /// </summary>
        /// <param name="table_id"></param>
        /// <param name="key"></param>
        /// <param name="secretKey"></param>
        /// <param name="fields"></param>
        /// <param name="orderby"></param>
        /// <param name="page_size"></param>
        /// <param name="page_index"></param>
        /// <param name="output"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        public static MapResponse<CloudSearchData> Search(string table_id,
            string key,
            string secretKey,
            string fields = null,
            string orderby = null,
            int? page_size = 10,
            int? page_index = null,
            int? page_next=null,
            string output = null,
            string callback = null)
        {
            string query = GetRequestBuilder.Create(secretKey, "/place_cloud/data/list")
                .WithKeyValue("key", key)
                .WithKeyValue("table_id", table_id)
                .WithKeyValue("fields", fields)
                .WithKeyValue("orderby", orderby)
                .WithKeyValue("page_size", page_size)
                .WithKeyValue("page_index", page_index)
                .WithKeyValue("page_next", page_next)
                .WithKeyValue("output", output)
                .WithKeyValue("callback", callback)
                .BuildQueryString();
            string url = host + query;
            var response = Get<MapResponse<CloudSearchData>>(url, out string body);
            response.Body = body;
            return response;
        }

        /// <summary>
        /// 周边搜索（圆形范围）
        /// </summary>
        /// <param name="table_id">表id，即表的唯一标识（table_id在表创建后由系统自动生成，可在地点云数据管理台查询得到）</param>
        /// <param name="key">开发者key：</param>
        /// <param name="secretKey">开发者密钥</param>
        /// <param name="location">搜索中心点坐标 示例:location=39.976194,116.317987</param>
        /// <param name="radius">半径，单位：米，默认5,000米，最大支持10,000米，参数值超过10,000米时，只返回10,000米内的数据</param>
        /// <param name="spatial_rel">空间搜索方式，取值：</param>
        /// <param name="auto_extend">当前范围无结果时，是否自动扩大搜索，取值：0 [默认]不自动扩大范围 1 自动扩大范围：当radius设置小于5,000米且搜索无结果 时，会扩大到 5,000米，再无结果时会自动扩展到10,000米</param>
        /// <param name="keyword">搜索关键字。示例:keyword=男装</param>
        /// <param name="filter">按字段值筛选，支持设置为可搜索的自定义number型字段及预设可搜索的系统字段</param>
        /// <param name="orderby">排序方式</param>
        /// <param name="fields">指定返回字段：返回文本数据大小对性能影响较大，建议只获取需要的字段</param>
        /// <param name="page_size">每页条数：默认10条，最大支持200条</param>
        /// <param name="page_index">页码，默认第1页</param>
        /// <param name="output">返回格式：支持JSON/JSONP，默认JSON</param>
        /// <param name="callback">JSONP方式回调函数</param>
        /// <returns></returns>
        public static MapResponse<CloudSearchData> SearchNearby(string table_id,
            string key,
            string secretKey,
            string location,
            int radius = 5000,
            int spatial_rel = 0,
            int auto_extend = 0,
            string keyword = null,
            string filter = null,
            string orderby = null,
            string fields = null,
            int page_size = 10,
            int page_index = 1,
            string output = null,
            string callback = null)
        {
            string query = GetRequestBuilder.Create(secretKey, "/place_cloud/search/nearby")
                .WithKeyValue("key", key)
                .WithKeyValue("table_id", table_id)
                .WithKeyValue("location", location)
                .WithKeyValue("radius", radius.ToString())
                .WithKeyValue("spatial_rel", spatial_rel.ToString())
                .WithKeyValue("auto_extend", auto_extend.ToString())
                .WithKeyValue("keyword", keyword)
                .WithKeyValue("filter", filter)
                .WithKeyValue("orderby", orderby)
                .WithKeyValue("fields", fields)
                .WithKeyValue("page_size", page_size.ToString())
                .WithKeyValue("page_index", page_index.ToString())
                .WithKeyValue("output", output)
                .WithKeyValue("callback", callback)
                .BuildQueryString();
            string url = host + query;
            var response = Get<MapResponse<CloudSearchData>>(url, out string body);
            response.Body = body;
            return response;
        }

        /// <summary>
        /// 区域搜索
        /// </summary>
        /// <param name="table_id">表id，即表的唯一标识（table_id在表创建后由系统自动生成，可在地点云数据管理台查询得到）</param>
        /// <param name="key">开发者key</param>
        /// <param name="secretKey">开发者密钥</param>
        /// <param name="region">搜索区域名称，格式要求：省,市,区（逗号分割）支持行政区划代码（adcode）示例： 
        /// <para>示例一:region=北京市,海淀区</para>
        /// <para>示例二:region=130681</para>
        /// </param>
        /// <param name="keyword">搜索关键字</param>
        /// <param name="filter">按字段值筛选，支持设置为可搜索的自定义number型字段及预设可搜索的系统字段（详见数据定义）</param>
        /// <param name="orderby">排序方式</param>
        /// <param name="fields">指定返回字段：返回文本数据大小对性能影响较大，建议只获取需要的字段</param>
        /// <param name="page_size">每页条数：默认10条，最大支持200条</param>
        /// <param name="page_index">页码，默认第1页</param>
        /// <param name="output">返回格式：支持json(默认)及jsonp</param>
        /// <param name="callback">JSONP方式回调函数</param>
        /// <returns></returns>
        public static MapResponse<CloudSearchData> SearchRegion(string table_id,
            string key,
            string secretKey,
            string region,
            string keyword = null,
            string filter = null,
            string orderby = null,
            string fields = null,
            int page_size = 10,
            int page_index = 1,
            string output = null,
            string callback = null)
        {
            string query = GetRequestBuilder.Create(secretKey, "/place_cloud/search/region")
                .WithKeyValue("key", key)
                .WithKeyValue("table_id", table_id)
                .WithKeyValue("region", region)
                .WithKeyValue("keyword", keyword)
                .WithKeyValue("filter", filter)
                .WithKeyValue("orderby", orderby)
                .WithKeyValue("fields", fields)
                .WithKeyValue("page_size", page_size.ToString())
                .WithKeyValue("page_index", page_index.ToString())
                .WithKeyValue("output", output)
                .WithKeyValue("callback", callback)
                .BuildQueryString();
            string url = host + query;
            var response = Get<MapResponse<CloudSearchData>>(url, out string body);
            response.Body = body;
            return response;
        }

        /// <summary>
        /// 矩形搜索
        /// </summary>
        /// <param name="table_id">表id，即表的唯一标识（table_id在表创建后由系统自动生成，可在地点云数据管理台查询得到）</param>
        /// <param name="key">开发者key</param>
        /// <param name="secretKey">开发者密钥</param>
        /// <param name="rectangle">矩形范围由左下（西南）和右上（东北）两个坐标表达，格式：lat,lng<左下/西南>;lat,lng<右上/东北>
        /// <para>示例:39.905444,116.319157;39.921244,116.337696</para>
        /// </param>
        /// <param name="spatial_rel">空间搜索方式，取值
        /// <para>0 [默认]搜索指定范围内的POI点(location，图1)</para>
        /// <para>1 搜索指定范围内的POI面(polygon，图2)，包括：相交、包含</para>
        /// </param>
        /// <param name="keyword">搜索关键字</param>
        /// <param name="filter">按字段值筛选，支持设置为可搜索的自定义number型字段及预设可搜索的系统字段（详见数据定义）</param>
        /// <param name="orderby">排序方式</param>
        /// <param name="fields">指定返回字段：返回文本数据大小对性能影响较大，建议只获取需要的字段</param>
        /// <param name="page_size">每页条数：默认10条，最大支持200条</param>
        /// <param name="page_index">页码，默认第1页</param>
        /// <param name="output">返回格式：支持json(默认)及jsonp</param>
        /// <param name="callback">JSONP方式回调函数</param>
        /// <returns></returns>
        public static MapResponse<CloudSearchData> SearchRectangle(string table_id,
            string key,
            string secretKey,
            string rectangle,
            int spatial_rel = 0,
            string keyword = null,
            string filter = null,
            string orderby = null,
            string fields = null,
            int page_size = 10,
            int page_index = 1,
            string output = null,
            string callback = null)
        {
            string query = GetRequestBuilder.Create(secretKey, "/place_cloud/search/rectangle")
                .WithKeyValue("key", key)
                .WithKeyValue("table_id", table_id)
                .WithKeyValue("rectangle", rectangle)
                .WithKeyValue("spatial_rel", spatial_rel.ToString())
                .WithKeyValue("keyword", keyword)
                .WithKeyValue("filter", filter)
                .WithKeyValue("orderby", orderby)
                .WithKeyValue("fields", fields)
                .WithKeyValue("page_size", page_size.ToString())
                .WithKeyValue("page_index", page_index.ToString())
                .WithKeyValue("output", output)
                .WithKeyValue("callback", callback)
                .BuildQueryString();
            string url = host + query;
            var response = Get<MapResponse<CloudSearchData>>(url, out string body);
            response.Body = body;
            return response;
        }

        /// <summary>
        /// 围栏搜素
        /// </summary>
        /// <param name="table_id">表id，即表的唯一标识（table_id在表创建后由系统自动生成，可在地点云数据管理台查询得到）</param>
        /// <param name="key">开发者key</param>
        /// <param name="secretKey">开发者密钥</param>
        /// <param name="location">搜索中心点坐标</param>
        /// <param name="keyword">搜索关键字</param>
        /// <param name="filter">按字段值筛选，支持设置为可搜索的自定义number型字段及预设可搜索的系统字段（详见数据定义）</param>
        /// <param name="orderby">排序方式</param>
        /// <param name="fields">指定返回字段：返回文本数据大小对性能影响较大，建议只获取需要的字段</param>
        /// <param name="page_size">每页条数：默认10条，最大支持200条</param>
        /// <param name="page_index">页码，默认第1页</param>
        /// <param name="output">返回格式：支持json(默认)及jsonp</param>
        /// <param name="callback">JSONP方式回调函数</param>
        /// <returns></returns>
        public static MapResponse<CloudSearchData> SearchContain(string table_id,
            string key,
            string secretKey,
            string location,
            string keyword = null,
            string filter = null,
            string orderby = null,
            string fields = null,
            int page_size = 10,
            int page_index = 1,
            string output = null,
            string callback = null)
        {
            string query = GetRequestBuilder.Create(secretKey, "/place_cloud/search/contain")
                .WithKeyValue("key", key)
                .WithKeyValue("table_id", table_id)
                .WithKeyValue("location", location)
                .WithKeyValue("keyword", keyword)
                .WithKeyValue("filter", filter)
                .WithKeyValue("orderby", orderby)
                .WithKeyValue("fields", fields)
                .WithKeyValue("page_size", page_size.ToString())
                .WithKeyValue("page_index", page_index.ToString())
                .WithKeyValue("output", output)
                .WithKeyValue("callback", callback)
                .BuildQueryString();
            string url = host + query;
            var response = Get<MapResponse<CloudSearchData>>(url, out string body);
            response.Body = body;
            return response;
        }
    }
}
